
<template>
  <div :style="{ border: '1px inset #D9D9D9', width: '99%' }">
    <Row>
      <!-- <Col :span="6">
        <Button v-if="defaultCfg.config.show_slack" @click="toggleSlack">显示裕度</Button>
        <Button v-if="defaultCfg.config.highlight_critical_path"
          @click="updateCriticalPath">显示关键路径</Button>
      </Col> -->

      <Form :labelWidth="110" style="width: 100%; background: white">
        <Row style="align-items: center">
          <span style="padding: 0 10px">时间粒度</span>
          <FieldCell
            :value="'hour'"
            :config="{
              type: 'radio',
              options: [
                { label: '小时', value: 'hour' },
                { label: '日', value: 'day' },
                { label: '周', value: 'week' },
              ],
            }"
            @change="setSelectedScales($event)"
          />
          <Button @click="submit">保存</Button>
          <Button @click="exportExcel">导出Excel</Button>
        </Row>
      </Form>
      <Col :span="12">
        <!-- <Button @click="refresh">刷新</Button> -->
      </Col>
    </Row>
    <div ref="ganttEl" class="left-container"></div>
    <Modal
      title="配置计划"
      :width="80"
      :styles="{ maxWidth: '800px' }"
      v-model="showForm"
      footer-hide
      :closable="false"
      :mask-closable="false"
    >
      <Form :model="formData" :labelWidth="110">
        <Row>
          <Col :span="24">
            <FieldItem
              v-model="formData.text"
              :config="{ type: 'textarea', clearable: false }"
              :formItemProps="{ label: '描述' }"
            />
          </Col>
          <Col :span="12">
            <FieldItem
              v-model="formData.planned_start"
              :config="{ type: 'date', clearable: false }"
              :formItemProps="{ label: '计划开始日期' }"
            />
          </Col>
          <Col :span="12">
            <FieldItem
              v-model="formData.planned_end"
              :config="{ type: 'date', clearable: false }"
              :formItemProps="{ label: '计划结束日期' }"
            />
          </Col>
          <Col :span="8">
            <FieldItem
              v-model="formData.start_date"
              :config="{ type: 'date', clearable: false }"
              :formItemProps="{ label: '实际开始时间' }"
            />
          </Col>
          <Col :span="8">
            <FieldItem
              v-model="formData.end_date"
              :config="{ type: 'date', clearable: false }"
              :formItemProps="{ label: '实际结束时间' }"
            />
          </Col>
          <!-- <Col :span="6">
        <FieldItem v-model="formData.duration" :config="{ type: 'number' }" :formItemProps="{ label: '期间' }"/>
        </Col> -->
        </Row>
      </Form>
      <div class="ivu-modal-footer">
        <Button @click="onRemove" style="float: left">删除</Button>
        <Button @click="onClose" class="ivu-mr">取消</Button>
        <Button @click="onSave" type="primary">保存</Button>
      </div>
    </Modal>
  </div>
</template>

<script>
import gantt from "public/3thComponents/gantt"; // 引入模块
import "../ganttExport.js";
import "public/3thComponents/gantt/codebase/dhtmlxgantt.css";
import dayjs from "dayjs";

let initData = [
  // {
  //   // parentId: "1",
  //   data: {
  //     id: "a1",
  //     text: "任务1",
  //     start_date: "2023-09-02 00:00",
  //     end_date: "2023-09-07 00:00",
  //     planned_start: "2023-09-01 00:00",
  //     planned_end: "2023-09-07 00:00",
  //     progress: 0.35,
  //   },
  // },
  // {
  //   parentId: "a1",
  //   data: {
  //     id: "a-1",
  //     text: "任务2",
  //     start_date: "2023-08-29 00:00",
  //     end_date: "2023-08-31 00:00",
  //     planned_start: "2023-08-30 00:00",
  //     planned_end: "2023-08-31 00:00",
  //     progress: 0.5,
  //   },
  // },
  // {
  //   parentId: "a1",
  //   data: {
  //     id: "a-2",
  //     text: "任务3",
  //     start_date: "2023-09-01 00:00",
  //     end_date: "2023-09-02 00:00",
  //     planned_start: "2023-08-31 00:00",
  //     planned_end: "2023-09-02 00:00",
  //     progress: 0.3,
  //   },
  // },
  // {
  //   type: "link",
  //   data: {
  //     id: "link1",
  //     source: "a-1",
  //     target: "a-2",
  //     type: gantt.config.links.finish_to_start,
  //   },
  // },
  {
    data: {
      id: "a-2",
      // "end_date": "2024-05-22",
      text: "新计划",
      start_date: "2024-05-21",
      duration: 1,
      planned_start: "2024-05-21",
      planned_end: "2024-05-24",
    },
  },
];
let demo_tasks = {
  data: [
    {
      id: 11,
      text: "Project #1",
      start_date: "2023-03-28",
      planned_start: "2023-03-28",
      planned_end: "2023-04-28",
      duration: "11",
      progress: 0.6,
      open: true,
    },
    {
      id: 1,
      text: "Project #2",
      start_date: "01-04-2023",
      duration: "18",
      progress: 0.4,
      open: true,
    },
  ],
  links: [
    { id: "1", source: "1", target: "2", type: "1" },
    { id: "2", source: "2", target: "3", type: "0" },
    { id: "3", source: "3", target: "4", type: "0" },
    { id: "4", source: "2", target: "5", type: "2" },
    { id: "5", source: "2", target: "6", type: "2" },
    { id: "6", source: "3", target: "7", type: "2" },
    { id: "7", source: "4", target: "8", type: "2" },
    { id: "8", source: "4", target: "9", type: "2" },
    { id: "9", source: "4", target: "10", type: "2" },
    { id: "10", source: "11", target: "12", type: "1" },
    { id: "11", source: "11", target: "13", type: "1" },
    { id: "12", source: "11", target: "14", type: "1" },
    { id: "13", source: "11", target: "15", type: "1" },
    { id: "14", source: "11", target: "16", type: "1" },
    { id: "15", source: "13", target: "17", type: "1" },
    { id: "16", source: "17", target: "18", type: "0" },
    { id: "17", source: "18", target: "19", type: "0" },
    { id: "18", source: "19", target: "20", type: "0" },
    { id: "19", source: "15", target: "21", type: "2" },
    { id: "20", source: "15", target: "22", type: "2" },
    { id: "21", source: "15", target: "23", type: "2" },
  ],
};
export default {
  name: "starPlan",
  // components: { FieldCell },
  data() {
    let _this = this;
    return {
      task:{
        data:[],
        link:[]
      },
      groupbyOptions: [],
      defaultCfg: {
        rowLayout: {
          // the default layout
          css: "gantt_container",
          rows: [
            {
              cols: [
                {
                  view: "grid",
                  group: "grids",
                  scrollX: "scrollHor",
                  scrollY: "scrollVer",
                }, //config: mainGridConfig,
                { resizer: true, width: 1 },
                {
                  view: "timeline",
                  scrollX: "scrollHor",
                  scrollY: "scrollVer",
                },
                { view: "scrollbar", id: "scrollVer", group: "vertical" },
              ],
              gravity: 100,
            },
          ],
        },
        rowResource: [
          // a custom layout
          { resizer: true, width: 1 },
          {
            cols: [
              {
                view: "grid",
                group: "grids",
                id: "resourceGrid",
                bind: "resource",
                scrollY: "resourceVScroll",
              }, //config:resourceGridConfig,
              { resizer: true, width: 1 },
              {
                view: "timeline",
                id: "resourceTimeline",
                scrollX: "scrollHor",
                bind: "resource",
                bindLinks: null,
                scrollY: "resourceVScroll",
              }, //layers: resourceLayers,
              { view: "scrollbar", id: "resourceVScroll", group: "vertical" },
            ],
            gravity: 50,
          },
        ],
        rowScroll: { view: "scrollbar", id: "scrollHor" },
        colLayout: {
          css: "gantt_container",
          cols: [
            {
              width: 400,
              min_width: 300,
              rows: [
                {
                  view: "grid",
                  scrollable: true,
                  scrollX: "gridScroll",
                  scrollY: "scrollVer",
                },
                { view: "scrollbar", id: "gridScroll", group: "horizontal" },
              ],
            },
            { resizer: true, width: 1 },
            {
              rows: [
                {
                  view: "timeline",
                  scrollX: "scrollHor",
                  scrollY: "scrollVer",
                },
                { view: "scrollbar", id: "scrollHor", group: "horizontal" },
              ],
            },
          ],
        },
        colResource: [
          [
            {
              view: "grid",
              group: "grids",
              id: "resourceGrid",
              bind: "resource",
              scrollY: "resourceVScroll",
            },
          ],
          [
            {
              view: "timeline",
              id: "resourceTimeline",
              scrollX: "scrollHor",
              bind: "resource",
              bindLinks: null,
              scrollY: "resourceVScroll",
            },
          ],
        ],
        colScroll: { view: "scrollbar", id: "scrollVer" },
        columns: {
          wbs: {
            name: "wbs",
            label: "序号",
            resize: true,
            width: 40,
            template: gantt.getWBSCode,
          },
          text: {
            name: "text",
            label: "任务名称",
            tree: true,
            resize: true,
            width: "*",
          },
          holder: { name: "holder", label: "负责人", resize: true, width: "*" },
          workunitName: {
            name: "workunitName",
            label: "工位名称",
            resize: true,
            width: "*",
          },
          workunit: {
            name: "workunit",
            label: "工位ID",
            resize: true,
            width: "*",
            hide: true,
          },
          // constraint_type:{name:"constraint_type",label:"约束",hide:true,resize:true,width:"*",align:"center"},
          // constraint_date:{name:"constraint_date",label:"约束时间",hide:true,resize:true,width:"*",align:"center"},
          planned_start: {
            name: "planned_start",
            label: "计划开始时间",
            hide: false,
            resize: true,
            width: "*",
            align: "center",
          },
          planned_end: {
            name: "planned_end",
            label: "计划结束时间",
            hide: false,
            resize: true,
            width: "*",
            align: "center",
          },
          start_date: {
            name: "start_date",
            label: "实际开始时间",
            resize: true,
            width: "*",
            align: "center",
          },
          end_date: {
            name: "end_date",
            label: "实际结束时间",
            hide: false,
            resize: true,
            width: "*",
            align: "center",
          },
          duration: {
            name: "duration",
            label: "期间",
            resize: true,
            align: "center",
          },
          progress: {
            name: "progress",
            label: "进度",
            resize: true,
            align: "center",
            template: (item) => {
              let num = (item.progress * 100).toFixed(1);
              return num + "%";
            },
          },
          add: { name: "add", label: "", width: 44 },
        },
        sections: {
          reference: {
            name: "reference",
            label: "更多...",
            height: 1,
            width: 0,
            map_to: "task",
            type: "textarea",
            button: "reference",
          },
          task: {
            name: "task",
            label: "任务",
            height: 30,
            map_to: "text",
            type: "textarea",
            focus: true,
          },
          description: {
            name: "description",
            label: "描述",
            height: 60,
            map_to: "desc",
            type: "textarea",
          },
          type: {
            name: "type",
            label: "任务类型",
            type: "typeselect",
            map_to: "type",
          },
          holder: {
            name: "holder",
            label: "负责人",
            type: "select",
            map_to: "holder",
          },
          workunit: {
            name: "workunit",
            label: "工位",
            type: "select",
            map_to: "workunit",
          },
          priority: {
            name: "priority",
            label: "优先级",
            height: 22,
            map_to: "priority",
            type: "select",
            options: [
              { key: 1, label: "High" },
              { key: 2, label: "Normal" },
              { key: 3, label: "Low" },
            ],
          },
          split: {
            name: "split",
            label: "显示",
            type: "checkbox",
            map_to: "render",
            options: [{ key: "split", label: "Split Task" }],
          },
          // constraint:{name:"constraint",label:"约束",type:"constraint"},
          actual: {
            name: "actual",
            label: "实际时间",
            height: 25,
            map_to: "auto",
            type: "duration",
          },
          baseline: {
            name: "baseline",
            label: "计划时间",
            height: 25,
            type: "duration",
            map_to: { start_date: "planned_start", end_date: "planned_end" },
          },
        },
        sectionButtons: {
          save: {
            name: "gantt_save_btn",
            id: "icon_save",
            label: "保存",
            position: "left",
          },
          cancel: {
            name: "gantt_cancel_btn",
            id: "icon_cancel",
            label: "取消",
            position: "left",
          },
          complete: {
            name: "complete_button",
            id: "complete_button",
            label: "完成",
            position: "left",
          },
          delete: {
            name: "gantt_delete_btn",
            id: "icon_delete",
            label: "删除",
            position: "right",
          },
        },
        config: {
          /*date格式*/
          date_format: "%Y-%m-%d %H:%i:%s",
          /*附加标识线*/
          marker: true,
          autofit: true,
          autoscroll: true,
          autoscroll_speed: 50,
          /*project 合并后依然具有收起图标*/
          open_split_tasks: true,
          /*auto scheduling*/
          auto_scheduling: true,
          /*drag-drop*/
          order_branch: "marker",
          order_branch_free: true,
          /*显示评估和可能区间*/
          highlight_critical_path: true,
          show_slack: true,
          /*设置工作时间*/
          work_time: true,
          duration_unit: "day",
          /*task操作*/
          cascade_delete: true,
          /*列头排序操作*/
          sort: true,
          group: true,
          // auto_scheduling:true,
          auto_scheduling_strict: true,
          auto_scheduling_initial: true,
          auto_scheduling_compatibility: true,
          auto_scheduling_descendant_links: true,
          refresh: true,
        },
      },
      gantt: null,
      ganttEl: null,
      defaultTpl: {},
      curTaskId: null,
      showForm: false,
      formData: {},
    };
  },
  mounted() {
    this.init();
    console.log(this.gantt.config);
  },
  destroyed() {
    this.gantt.destructor();
  },
  methods: {
    init() {
      this.gantt = gantt;
      this.ganttEl = this.$refs._ganttEl;
      this.updateLocale();
      this.setConfig();
      this.initPlanned();
      this.gantt.plugins({ auto_scheduling: true });
      this.gantt.init(this.$refs.ganttEl);
      this.parse();
      this.addSection();
    },
    addSection() {
      gantt.showLightbox = (id) => {
        this.curTaskId = id;
        let task = gantt.getTask(id);
        console.log("file: JGantt.vue:310  addSection  task:", id, task);

        if (task.$new) {
          this.formData.end_date = dayjs(task.start_date)
            .add(1, "day")
            .toDate();
        } else {
          this.formData.end_date = task.end_date;
        }
        this.formData.text = task.text;
        this.formData.start_date = task.start_date;
        this.formData.duration = task.duration;
        this.formData.planned_start = task.planned_start;
        this.formData.planned_end = task.planned_end;
        this.showForm = true;
      };
      gantt.attachEvent("onAfterTaskAdd", function (id, item) {
        console.log(
          "file: JGantt.vue:285  gantt.attachEvent  id,item:",
          id,
          item
        );
      });
      // gantt.config.lightbox.sections = [
      //   // ...gantt.config.lightbox.sections,
      //     {
      //         "name": "description",
      //         "height": 70,
      //         "map_to": "text",
      //         "type": "textarea",
      //         "focus": true,
      //     },
      //     {
      //         "name": "time",
      //         "type": "duration",
      //         "map_to": "auto",
      //     },
      //   {
      //       "name": "planned_start",
      //       // "height": 70,
      //       "map_to": "auto",
      //       "type": "time",
      //       "single_date": true,
      //       // "time_format": ["%Y", "%m", "%d"],
      //   },
      // ];
    },
    getDefault() {
      return this.definedDef;
    },
    initPlugin() {
      let plugins = {};
      if (gantt.config.auto_scheduling) {
        plugins["auto_scheduling"] = true;
      }
      if (gantt.config.highlight_critical_path) {
        plugins["critical_path"] = true;
      }
      if (gantt.config.group) {
        plugins["grouping"] = true;
      }
      if (gantt.config.marker) {
        plugins["marker"] = true;
      }
      gantt.plugins(plugins);
      if (plugins.auto_scheduling) {
        gantt.config.auto_scheduling = true;
      }
      let dateToStr = gantt.date.date_to_str(gantt.config.task_date);
      gantt.addMarker({
        start_date: new Date(),
        css: "today",
        text: "Now",
        title: "今天" + dateToStr(new Date()),
      });
    },
    initSlack() {
      /* show slack */
      let totalSlackColumn = {
        name: "totalSlack",
        align: "center",
        resize: true,
        width: 70,
        hide: true,
        label: "Total slack",
        template: function (task) {
          if (gantt.isSummaryTask(task)) {
            return "";
          }
          return gantt.getTotalSlack(task);
        },
      };
      let freeSlackColumn = {
        name: "freeSlack",
        align: "center",
        resize: true,
        width: 70,
        hide: true,
        label: "Free slack",
        template: function (task) {
          if (gantt.isSummaryTask(task)) {
            return "";
          }
          return gantt.getFreeSlack(task);
        },
      };

      gantt.config.columns = gantt.config.columns.concat([
        freeSlackColumn,
        totalSlackColumn,
      ]);

      gantt.config.show_slack = false;
      gantt.addTaskLayer(function addSlack(task) {
        if (!gantt.config.show_slack) {
          return null;
        }

        let slack = gantt.getFreeSlack(task);

        if (!slack) {
          return null;
        }

        let state = gantt.getState().drag_mode;

        if (state == "resize" || state == "move") {
          return null;
        }

        let slackStart = new Date(task.end_date);
        let slackEnd = gantt.calculateEndDate(slackStart, slack);
        let sizes = gantt.getTaskPosition(task, slackStart, slackEnd);
        let el = document.createElement("div");

        el.className = "slack";
        el.style.left = sizes.left + "px";
        el.style.top = sizes.top + 2 + "px";
        el.style.width = sizes.width + "px";
        el.style.height = sizes.height + "px";

        return el;
      });
    },
    initGroup() {
      let groupbyOptions = [{ label: "(取消分组)", value: "false" }];
      if (gantt.config.group == true) {
        gantt.config.columns.map((item) => {
          if (item.name != "add") {
            groupbyOptions.push({ label: item.label, value: item.name });
          }
        });
      } else {
        groupbyOptions = groupbyOptions.concat(gantt.config.group);
      }
      this.groupbyOptions = groupbyOptions;
      gantt.templates.task_row_class = function (start, end, task) {
        if (task.$virtual) return "summary-row";
      };
      gantt.templates.task_class = function (start, end, task) {
        if (task.$virtual) return "summary-bar";
      };
    },
    initTpl() {
      let tpl = {
        text: "",
        id: "",
        parent: "",
        link: "",
        start_date: "",
        end_date: "",
        planned_start: "",
        planned_end: "",
        duration: 0,
        progress: 0,
        holder: "",
        workunit: "",
        type: "",
      };
      if (Object.keys(this.tpl).length > 0) {
        tpl = this.tpl;
      }
      tpl["id"] = "";
      tpl["parent"] = "";
      tpl["link"] = "";
      this.defaultTpl = tpl;
    },
    initEvent() {
      let _this = this;
      gantt.form_blocks.textarea.button_click = function (
        index,
        button,
        shead,
        sbody
      ) {
        let id = gantt.getState().lightbox;
        let task = gantt.getTask(id);
        _this.$emit("reference", gantt, id, task, _this.data);
      };
      gantt.attachEvent("onLightboxButton", function (button_id, node, e) {
        if (button_id == "complete_button") {
          let id = gantt.getState().lightbox;
          gantt.getTask(id).progress = 1;
          gantt.updateTask(id);
          gantt.hideLightbox();
        }
      });
      gantt.attachEvent("onAfterTaskAdd", function (id, item) {
        _this.getData();
        _this.$emit("addTask", gantt, id, item, _this.data);
      });
      gantt.attachEvent("onAfterTaskUpdate", function (id, item) {
        _this.getData();
        _this.$emit("updateTask", gantt, id, item, _this.data);
      });
      gantt.attachEvent("onAfterTaskDelete", function (id, item) {
        _this.getData();
        _this.$emit("deleteTask", gantt, id, item, _this.data);
      });
      gantt.attachEvent("onAfterLinkAdd", function (id, item) {
        _this.getData();
        _this.$emit("addLink", gantt, id, item, _this.data);
      });
      gantt.attachEvent("onAfterLinkDelete", function (id, item) {
        _this.getData();
        _this.$emit("deleteLink", gantt, id, item, _this.data);
      });
      gantt.attachEvent("onAfterLinkUpdate", function (id, item) {
        _this.getData();
        _this.$emit("updateLink", gantt, id, item, _this.data);
      });
    },
    toggleSlack(e) {
      console.log("file: JGantt.vue:812  toggleSlack  e:", e);
      if (e.currentTarget.innerHTML == "显示裕度") {
        e.currentTarget.innerHTML = "隐藏裕度";
        //declaring custom config
        gantt.config.show_slack = true;
      } else {
        e.currentTarget.innerHTML = "显示裕度";
        gantt.config.show_slack = false;
      }
      gantt.render();
    },
    updateCriticalPath(e) {
      if (e.currentTarget.innerHTML == "显示关键路径") {
        e.currentTarget.innerHTML = "隐藏关键路径";
        gantt.config.highlight_critical_path = true;
      } else {
        e.currentTarget.innerHTML = "显示关键路径";
        gantt.config.highlight_critical_path = false;
      }
      gantt.render();
    },
    groupBy(v) {
      if (v == "false") {
        gantt.groupBy(false);
        return;
      }
      let m = false;
      let mapName = "";
      let property = v;
      gantt.config.columns.map((item) => {
        if (item.name === v) {
          if (Object.keys(item).includes("mapOption")) {
            m = {};
            mapName = item.mapName;
            property = mapName;
            item.mapOption.map((mapO) => {
              m[mapO.key] = mapO;
            });
          }
        }
      });
      let p = {};
      if (m) {
        this.data.tasks.map((item) => {
          if (!Object.keys(p).includes(item[mapName])) {
            p[item[mapName]] = {
              key: item[mapName],
              label: m[item[mapName]].label,
            };
          }
        });
      } else {
        this.data.tasks.map((item) => {
          if (!Object.keys(p).includes(item[v])) {
            p[item[v]] = { key: item[v], label: item[v] };
          }
        });
      }
      let groups = Object.values(p);
      gantt.groupBy({
        relation_property: property,
        groups: groups,
        group_id: "key",
        group_text: "label",
      });
    },
    getData() {
      // this.$nextTick(()=>{
      let tasks = gantt.getTaskByTime();
      let links = gantt.getLinks();
      let newtasks = [];
      let newlinks = [];
      if (tasks.length > 0) {
        tasks.map((item) => {
          newtasks.push(
            this.tools.lodash.merge(
              this.tools.lodash.cloneDeep(this.defaultTpl),
              item
            )
          );
        });
      }
      let dateToStr = gantt.date.date_to_str("%Y-%m-%d %H:%i:%s");
      let formattasks = [];
      newtasks.map((item) => {
        Object.keys(item).map((key) => {
          if (
            ["start_date", "end_date", "planned_start", "planned_end"].includes(
              key
            )
          ) {
            item[key] = dateToStr(item[key]);
          }
        });
        formattasks.push(item);
      });
      if (links.length > 0) {
        links.map((item, index) => {
          newlinks.push(Object.assign({}, item, { id: index + 1 }));
        });
      }
      this.$set(this.data, "tasks", formattasks);
      this.$set(this.data, "links", newlinks);
    },
    parse() {
      let task = {
        data: [],
        link: [],
      };
      let taskTpl = {
        id: "",
        text: "",
        planned_start: null,
        planned_end: null,
        start_date: null,
        end_date: null,
        duration: null,
        progress: null,
        open: true,
      };
      this.data.map((item) => {
        if (item.type === "routing") {
          task.data.push({
            id: item.id,
            text: item.values.name,
            planned_start: item.values.planStartTime,
            planned_end: item.values.planEndTime,
            start_date: item.values.startTime,
            end_date: item.values.endTime,
            duration: item.values.planStartTime,
            progress: item.values.progress,
            status: item.values.status,
            open: true,
          });
          item.hier.content.map((h) => {
            if (h.nodeType != "root") {
              task.data.push({
                id: h.id,
                linkId: h.link.linkId,
                parent: item.id,
              });
            }
          });
        }
      });
      this.data.map((item) => {
        if (item.type === "workCenter") {
          let row = task.data.find((t) => t.linkId === item.id);
          if (row) {
            row.text = item.values.name;
            row.planned_start = item.values.planStartTime;
            row.planned_end = item.values.planEndTime;
            row.start_date = item.values.startTime;
            row.end_date = item.values.endTime;
            row.duration = item.values.planStartTime;
            row.progress = item.values.progress;
            row.status = item.values.status;
            row.open = true;
          }
        }
      });
      this.gantt.parse(task);
      this.task = task;
      console.log(task);
      this.gantt.render();
    },
    setConfig() {
      let defaultConfig = {
        scales: {
          model: "select", //zoom,select
          selection: "hour",
        },
      };
      defaultConfig = this.tools.lodash.merge(defaultConfig, this.config);
      let config = {
        /**整体布局配置 */
        autoscroll: true, //滚动条自动扩展
        autoscroll_speed: 50, //滚动条速度
        row_height: 40, //行高

        /**grid布局配置 */
        autofit: true, //自动调整列宽

        /**timeline布局配置 */
        bar_height: 15, //柱状图高度
        scale_height: 80,
        min_column_width: 80,
        max_column_width: 180,
        fit_tasks: true, //按照任务的开始和结束时间调整甘特图时间轴宽度

        /**task配置 */
        auto_types: true, //自动识别任务类型
        cascade_delete: true, //层级删除

        /**日期配置 */
        work_time: true, //工作时间
        correct_work_time: true, //拖拽时错开休息时间
        date_format: "%Y-%m-%d %H:%i:%s", //日期转换格式
        date_grid: "%Y-%m-%d %H:%i:%s", //grid日期显示格式

        /*lightbox配置*/
        task_date: "%Y-%F-%d",
        buttons_left: ["gantt_delete_btn"],
        buttons_right: ["gantt_save_btn", "gantt_cancel_btn"],

        /*附加标识线*/
        marker: true,
        /*project 合并后依然具有收起图标*/
        open_split_tasks: true,
        /*auto scheduling*/
        // auto_scheduling:true,
        /*drag-drop*/
        order_branch: "marker",
        order_branch_free: true,
        /*显示评估和可能区间*/
        highlight_critical_path: true,
        show_slack: true,
        /*设置工作时间*/
        duration_unit: "day",
        /*task操作*/
        /*列头排序操作*/
        sort: true,
        group: true,
        refresh: true,
      };
      this.gantt.config = { ...this.gantt.config, ...config };
      this.initScales(defaultConfig.scales.model);
      this.initLayout();
      this.initColumns();
      return config;
    },
    updateLocale() {
      // 支持国际化
      let localeObj = { "zh-CN": "cn", "en-US": "en" };
      gantt.i18n.setLocale(localeObj[this.$i18n.locale]);
      gantt.i18n.setLocale({
        labels: {
          section_planned_start: "计划开始时间",
          section_planned_start: "计划开始时间",
          message_ok: this.lang.message_ok,
          new_task: this.lang.new_task,
          message_cancel: this.lang.message_cancel,
          dhx_save_btn: this.lang.icon_save,
          dhx_cancel_btn: this.lang.icon_cancel,
          dhx_delete_btn: this.lang.icon_delete,
          section_description: this.lang.section_description,
          section_time: this.lang.section_time,
        },
        date: {
          month_full: this.lang.month_full,
        },
      });
    },
    /*****数据格式*****************************************************/
    initColumns() {
      let columns = {
        wbs: {
          index: 0,
          name: "wbs",
          label: "序号",
          resize: true,
          width: 40,
          template: gantt.getWBSCode,
        },
        text: {
          index: 1,
          name: "text",
          label: "任务名称",
          tree: true,
          resize: true,
          width: 200,
        },
        // holder:{index:2,name:"holder",label:"负责人",resize:true,width:"*"},
        // workunitName:{index:3,name:"workunitName",label:"工位名称",resize:true,width:"*"},
        // workunit:{index:4,name:"workunit",label:"工位ID",resize:true,width:"*",hide:true},
        // constraint_type:{index:5,name:"constraint_type",label:"约束",hide:true,resize:true,width:"*",align:"center"},
        // constraint_date:{index:6,name:"constraint_date",label:"约束时间",hide:true,resize:true,width:"*",align:"center"},
        planned_start: {
          index: 7,
          name: "planned_start",
          label: "计划开始时间",
          hide: false,
          resize: true,
          width: 100,
          align: "center",
        },
        planned_end: {
          index: 8,
          name: "planned_end",
          label: "计划结束时间",
          hide: false,
          resize: true,
          width: 100,
          align: "center",
        },
        start_date: {
          index: 9,
          name: "start_date",
          label: "实际开始时间",
          resize: true,
          width: 100,
          align: "center",
        },
        end_date: {
          index: 10,
          name: "end_date",
          label: "实际结束时间",
          hide: false,
          resize: true,
          width: 100,
          align: "center",
        },
        duration: {
          index: 11,
          name: "duration",
          label: "期间",
          resize: true,
          width: 40,
          align: "center",
        },
        status: {
          index: 12,
          name: "status",
          label: "状态",
          resize: true,
          width: 40,
          align: "center",
        },
        progress: {
          index: 13,
          name: "progress",
          label: "进度",
          resize: true,
          width: 60,
          align: "center",
          template: (item) => {
            let num = (item.progress * 100).toFixed(1);
            return num + "%";
          },
        },
        add: { index: 100, name: "add", label: "", width: 44 },
      };
      this.gantt.config.columns = Object.values(columns);
    },
    initPlanned() {
      gantt.attachEvent("onTaskLoading", function (task) {
        task.planned_start = gantt.date.parseDate(
          task.planned_start,
          "%Y-%m-%d"
        );
        task.planned_end = gantt.date.parseDate(task.planned_end, "%Y-%m-%d");
        return true;
      });
      gantt.addTaskLayer({
        renderer: {
          render: function draw_planned(task) {
            if (task.planned_start && task.planned_end) {
              let sizes = gantt.getTaskPosition(
                task,
                dayjs(task.planned_start).toDate(),
                dayjs(task.planned_end).toDate()
              );
              let el = document.createElement("div");
              el.className = "baseline";
              el.style.left = sizes.left + "px";
              el.style.width = sizes.width + "px";
              el.style.top = sizes.top + gantt.config.bar_height + 13 + "px";
              return el;
            }
            return false;
          },
          // define getRectangle in order to hook layer with the smart rendering
          getRectangle: function (task, view) {
            if (task.planned_start && task.planned_end) {
              return gantt.getTaskPosition(
                task,
                task.planned_start,
                task.planned_end
              );
            }
            return null;
          },
        },
      });
      gantt.config.task_height = 16;
      gantt.config.row_height = 40;
    },
    /*****布局*****************************************************/
    initLayout() {
      let layout = {
        default: {
          css: "gantt_container",
          rows: [
            {
              cols: [
                { view: "grid", scrollX: "scrollHor", scrollY: "scrollVer" }, // the default grid view
                { resizer: true, width: 1 },
                {
                  view: "timeline",
                  scrollX: "scrollHor",
                  scrollY: "scrollVer",
                }, // the default timeline view
                { view: "scrollbar", id: "scrollVer" },
              ],
            },
            { view: "scrollbar", id: "scrollHor" },
          ],
        },
      };
      this.gantt.config.layout = layout.default;
    },
    // initLayout() {
    //   let resourceConfig = {
    //     scale_height: 30,
    //     scales: [{ unit: "day", step: 1, date: "%d %M" }],
    //     columns: [
    //       {
    //         name: "name",
    //         label: "Name",
    //         tree: true,
    //         width: 250,
    //         template: function (resource) {
    //           return resource.text;
    //         },
    //         resize: true,
    //       },
    //       {
    //         name: "allocated",
    //         label: "Allocated",
    //         align: "left",
    //         width: 100,
    //         template: function (resource) {
    //           var assignments = gantt.getResourceAssignments(resource.id);
    //           var result = 0;
    //           assignments.forEach(function (assignment) {
    //             var task = gantt.getTask(assignment.task_id);
    //             if (resource.type == "work") {
    //               result += task.duration * assignment.value;
    //             } else {
    //               result += assignment.value * 1;
    //             }
    //           });

    //           if (resource.type == "work") {
    //             result = "<b>" + result + "</b> hours";
    //           } else {
    //             result = "<b>" + result + "</b> " + resource.unit;
    //           }

    //           return result;
    //         },
    //         resize: true,
    //       },
    //     ],
    //   };
    //   let type =
    //     this.layout.type == "row" || this.layout.type == "col"
    //       ? this.layout.type
    //       : "row";
    //   let layout = this.defaultCfg[type + "Layout"];
    //   if (this.layout.definedDef) {
    //     Object.assign(layout, this.layout.definedDef);
    //   }
    //   if (this.layout.hasAdditional) {
    //     if (type == "row") {
    //       if (this.layout.additional.length == 0) {
    //         this.defaultCfg.rowResource.config = resourceConfig;
    //         layout.rows = layout.rows.concat(
    //           this.defaultCfg.rowResource,
    //           this.defaultCfg.rowScroll
    //         );
    //       } else {
    //         layout.rows = layout.rows.concat(
    //           this.layout.additional,
    //           this.defaultCfg.rowScroll
    //         );
    //       }
    //     }
    //   } else {
    //     layout.rows = layout.rows.concat(this.defaultCfg.rowScroll);
    //   }
    //   return layout;
    // },
    /*****时间轴*****************************************************/
    initScales(model) {
      let that = this;
      if (model === "select") {
        this.setSelectedScales("hour");
      } else if (model === "zoom") {
        this.setZoomScales();
      }
      this.gantt.attachEvent("onBeforeGanttRender", function () {
        that.setDateRange();
      });
    },
    setDateRange() {
      // this.gantt.attachEvent("onBeforeGanttRender", function () {
      //   var range = gantt.getSubtaskDates();
      //   if (range.start_date && range.end_date) {
      //     gantt.config.start_date = gantt.calculateEndDate(
      //       range.start_date,
      //       -4,
      //       scaleUnit
      //     );
      //     gantt.config.end_date = gantt.calculateEndDate(
      //       range.end_date,
      //       5,
      //       scaleUnit
      //     );
      //   }
      // });
      let data = this.gantt.getTaskByTime();
      let start_date, end_date;
      data.map((d) => {
        start_date = new Date(
          Math.min.apply(
            null,
            [d.start_date, d.end_date, d.planned_start, d.planned_end].map(
              function (date) {
                return date.getTime();
              }
            )
          )
        );
        end_date = new Date(
          Math.max.apply(
            null,
            [d.start_date, d.end_date, d.planned_start, d.planned_end].map(
              function (date) {
                return date.getTime();
              }
            )
          )
        );
      });
      if(start_date&&end_date){
        let scaleUnit = gantt.getState().scale_unit;
        gantt.config.start_date = gantt.calculateEndDate(
          start_date,
          -4,
          scaleUnit
        );
        gantt.config.end_date = gantt.calculateEndDate(
          end_date,
          5,
          scaleUnit
        );
      }
    },
    setZoomScales() {
      let hourToStr = gantt.date.date_to_str("%H:%i");
      let hourRangeFormat = function (step) {
        return function (date) {
          var intervalEnd = new Date(gantt.date.add(date, step, "hour") - 1);
          return hourToStr(date) + " - " + hourToStr(intervalEnd);
        };
      };
      let zoomConfig = {
        minColumnWidth: 50,
        maxColumnWidth: 180,
        levels: [
          [
            {
              unit: "month",
              step: 1,
              format: "%Y - %M",
            },
            {
              unit: "week",
              step: 1,
              format: function (date) {
                var dateToStr = gantt.date.date_to_str("%M %d");
                var endDate = gantt.date.add(date, +6, "day");
                var weekNum = gantt.date.date_to_str("%W")(date);
                return (
                  "Week #" +
                  weekNum +
                  ", " +
                  dateToStr(date) +
                  " - " +
                  dateToStr(endDate)
                );
              },
            },
            { unit: "day", step: 1, format: "%M%d 星期%D" },
          ],
          [
            { unit: "month", format: "%Y - %M", step: 1 },
            { unit: "day", format: "%M %d", step: 1 },
          ],
          // [
          //   { unit: "day", format: "%M %d", step: 1 },
          //   { unit: "hour", format: hourRangeFormat(12), step: 12 },
          // ],
          // [
          //   { unit: "day", format: "%d %M", step: 1 },
          //   { unit: "hour", format: hourRangeFormat(6), step: 6 },
          // ],
          [
            { unit: "day", format: "%Y - %M - %d", step: 1 },
            { unit: "hour", format: "%H:%i", step: 1 },
          ],
        ],
        // startDate: new Date("2023-02-27"),
        // endDate: new Date("2024-10-20"),
        useKey: "ctrlKey",
        trigger: "wheel",
        element: function () {
          return gantt.$root.querySelector(".gantt_task");
        },
      };
      this.gantt.ext.zoom.init(zoomConfig);
      this.initWorkTime();
    },
    setSelectedScales(level) {
      let that = this;
      switch (level) {
        case "hour":
          this.gantt.config.scales = [
            { unit: "day", format: "%Y - %M - %d", step: 1 },
            { unit: "hour", format: "%H:%i", step: 1 },
          ];
          break;
        case "day":
          this.gantt.config.scales = [
            { unit: "month", format: "%Y - %M", step: 1 },
            { unit: "day", format: "%M %d", step: 1 },
          ];
          break;
        case "week":
          var weekScaleTemplate = function (date) {
            var dateToStr = that.gantt.date.date_to_str("%d %M");
            var endDate = that.gantt.date.add(
              that.gantt.date.add(date, 1, "week"),
              -1,
              "day"
            );
            return dateToStr(date) + " - " + dateToStr(endDate);
          };
          this.gantt.config.scales = [
            {
              unit: "month",
              step: 1,
              format: "%Y - %M",
            },
            {
              unit: "week",
              step: 1,
              format: function (date) {
                var dateToStr = that.gantt.date.date_to_str("%M %d");
                var endDate = that.gantt.date.add(date, +6, "day");
                var weekNum = that.gantt.date.date_to_str("%W")(date);
                return (
                  "Week #" +
                  weekNum +
                  ", " +
                  dateToStr(date) +
                  " - " +
                  dateToStr(endDate)
                );
              },
            },
            { unit: "day", step: 1, format: "%M%d 星期%D" },
          ];
          break;
      }
      this.initWorkTime();
      this.gantt.render();
    },
    initWorkTime() {
      let that = this;
      if (this.holiday.length > 0) {
        this.holiday.map((date) => {
          that.gantt.setWorkTime({ date: new Date(date), hours: false });
        });
      }
      that.gantt.templates.scale_cell_class = function (date) {
        if (!that.gantt.isWorkTime(date)) {
          return "week_end";
        }
      };
      that.gantt.templates.timeline_cell_class = function (task, date) {
        if (!that.gantt.isWorkTime({ task: task, date: date })) {
          return "week_end";
        }
      };
    },
    /*****页面交互*****************************************************/
    exportExcel() {
      let col = this.tools.lodash.clone(gantt._serialize_columns());
      gantt.config.columns.forEach((c) => {
        if (c.hide === true) {
          let i = col.findIndex((f) => c.name === f.id);
          if (i > -1) {
            col.splice(i, 1);
          }
        }
      });
      col.forEach((c) => {
        if (c.id === "planned_start" || c.id === "planned_end") {
          c.type = "date";
        }
      });
      let exCol = col.filter((c) => c.id !== "_11" && c.id !== "_12");
      gantt.exportToExcel({
        columns: exCol,
        date_format: "yyyy-mm-dd",
      });
    },
    refresh() {
      gantt.render();
    },
    submit(e) {
      // this.getData();
      let tasks = gantt.getTaskByTime();
      let links = gantt.getLinks();
      let data = [];

      tasks.forEach((item) => {
        data.push({
          parentId: item.parent,
          data: {
            id: item.id,
            text: item.text,
            start_date: dayjs(item.start_date).format("YYYY-MM-DD"),
            end_date: dayjs(item.end_date).format("YYYY-MM-DD"),
            planned_start: dayjs(item.planned_start).format("YYYY-MM-DD"),
            planned_end: dayjs(item.planned_end).format("YYYY-MM-DD"),
            progress: item.progress,
          },
        });
      });
      links.forEach((item) => {
        data.push({
          type: "link",
          data: {
            id: item.id,
            source: item.source,
            target: item.target,
            type: gantt.config.links.finish_to_start,
          },
        });
      });

      localStorage.setItem("sys_productionPlan", JSON.stringify(data));
      console.log(tasks, links, data);
      this.$emit("submit", gantt, this.data);
      this.$Message.success("保存成功");
    },
    onSave() {
      let task = gantt.getTask(this.curTaskId);

      task.text = this.formData.text;
      task.start_date = new Date(this.formData.start_date);
      task.end_date = new Date(this.formData.end_date);
      // task.duration = this.formData.duration
      // task.end_date = dayjs(this.formData.start_date).add(this.formData.duration || 0, 'day').toDate()
      task.planned_start = new Date(this.formData.planned_start); //this.formData.planned_start;
      task.planned_end = new Date(this.formData.planned_end); //this.formData.planned_end;
      console.log(
        "file: JGantt.vue:368  onSave  task:",
        task,
        this.formData,
        this.curTaskId
      );

      if (task.$new) {
        // delete task.$new;
        gantt.addTask(task, task.parent);
      } else {
        gantt.updateTask(task.id);
      }

      gantt.hideLightbox();
      this.showForm = false;
    },
    onClose() {
      var task = gantt.getTask(this.curTaskId);

      if (task.$new) {
        gantt.deleteTask(task.id);
      }
      gantt.hideLightbox();
      this.showForm = false;
    },
    onRemove() {
      gantt.deleteTask(this.curTaskId);
      gantt.hideLightbox();
      this.showForm = false;
    },
  },
  watch: {
    "$i18n.locale"(val) {
      this.updateLocale();
      // scheduler.updateView()
      gantt.updateTask();
    },
  },
  computed: {
    lang() {
      return {
        "zh-CN": {
          new_task: "新计划",
          message_ok: "确认",
          message_cancel: "取消",
          icon_save: "保存",
          icon_cancel: "关闭",
          icon_delete: "删除",
          section_description: "描述",
          section_time: "时间范围",
          month_full: [
            "1月",
            "2月",
            "3月",
            "4月",
            "5月",
            "6月",
            "7月",
            "8月",
            "9月",
            "10月",
            "11月",
            "12月",
          ],
          Configure: "配置假期",
          holiday: "假期",
          weekend: "周末",
          all: "全部",
          team: "班组",
          teamClass: "班次",
        },
        "en-US": {
          new_task: "new plan",
          message_ok: "OK",
          message_cancel: "CANCEL",
          icon_save: "SAVE",
          icon_cancel: "CANCEL",
          icon_delete: "DELETE",
          section_description: "Description",
          section_time: "Time period",
          month_full: [
            "January",
            "February",
            "March",
            "April",
            "May",
            "June",
            "July",
            "August",
            "September",
            "October",
            "November",
            "December",
          ],
          Configure: "Configure holiday",
          holiday: "holiday",
          weekend: "weekend",
          all: "all",
          team: "team",
          teamClass: "team class",
        },
      }[this.$i18n.locale];
    },
  },
  props: {
    isToolbar: {
      default: true,
    },
    sections: {
      default: function () {
        return false;
      },
    },
    sectionButtons: {
      default: function () {
        return false;
      },
    },
    holiday: {
      default: function () {
        return [];
      },
    },
    data: {
      default: function () {
        return [
          {
            comments: null,
            updatedBy: null,
            values: {
              planStartTime: "2024-05-22 00:00:00",
              productId: null,
              name: "还原工艺路线",
              currentWorkCenter: "[]",
              planEndTime: "2024-05-23 00:00:00",
              startTime: "2024-05-21 09:33:47",
              endTime: "2024-05-23 00:00:00",
              status: "创建",
            },
            className: "ReductionRouting",
            updateTime: "2024-05-21 09:33:47",
            published: true,
            type: "routing",
            version: 1,
            deleteFlag: false,
            web: {},
            createdBy: null,
            createTime: "2024-05-21 09:33:47",
            name: "00d195fb6b57416d84c71341e9134dd9",
            id: 56,
            locked: 0,
            others: {},
            hier: {
              containerModel: "routing",
              className: "ReductionRouting",
              type: "chain",
              containerId: 56,
              content: [
                {
                  prev: [],
                  values: {
                    null: null,
                  },
                  name: "root",
                  link: {
                    linkModel: null,
                    linkId: null,
                    linkType: null,
                    linkClassName: null,
                  },
                  id: 239999,
                  nodeType: "root",
                  nodeId: "_root",
                  parentId: null,
                },
                {
                  prev: ["_root"],
                  values: {
                    null: null,
                  },
                  name: "workCenter",
                  link: {
                    linkModel: "workCenter",
                    linkId: 56,
                    linkType: "workCenter",
                    linkClassName: "ReductionWorkCenter",
                  },
                  id: 240000,
                  nodeType: "list",
                  nodeId: "179ly2aj769s00",
                  parentId: null,
                },
              ],
            },
          },
          {
            comments: null,
            updatedBy: null,
            values: {
              planStartTime: "2024-05-22 00:00:00",
              productId: 6,
              workNoticeId: null,
              name: "还原工作中心",
              planEndTime: "2024-05-23 00:00:00",
              startTime: "2024-05-21 09:33:47",
              workUnitId: null,
              endTime: "2024-05-23 00:00:00",
              materialId: null,
              status: "创建",
            },
            className: "ReductionWorkCenter",
            updateTime: "2024-05-21 09:33:48",
            published: true,
            type: "workCenter",
            version: 1.0,
            deleteFlag: false,
            web: {},
            createdBy: null,
            createTime: "2024-05-21 09:33:48",
            name: "6d938418ab0743e5a04c34c9c6f4f482",
            id: 56,
            locked: 0,
            others: {},
            hier: {
              containerModel: "workCenter",
              className: "ReductionWorkCenter",
              type: "tree",
              containerId: 56,
              content: [
                {
                  prev: null,
                  values: {},
                  name: "root",
                  link: {
                    linkModel: null,
                    linkId: null,
                    linkType: null,
                    linkClassName: null,
                  },
                  id: 240001,
                  nodeType: "root",
                  nodeId: "root",
                  parentId: "",
                },
                {
                  prev: null,
                  values: {
                    null: null,
                  },
                  name: "InputRecords",
                  link: {
                    linkModel: null,
                    linkId: null,
                    linkType: null,
                    linkClassName: null,
                  },
                  id: 240010,
                  nodeType: "list",
                  nodeId: "3bxcbqn7olk000",
                  parentId: "root",
                },
                {
                  prev: null,
                  values: {
                    null: null,
                  },
                  name: "InputSummary",
                  link: {
                    linkModel: null,
                    linkId: null,
                    linkType: null,
                    linkClassName: null,
                  },
                  id: 240011,
                  nodeType: "list",
                  nodeId: "3kg0yzhi7a0000",
                  parentId: "root",
                },
                {
                  prev: null,
                  values: {
                    null: null,
                  },
                  name: "InputSummaryRest",
                  link: {
                    linkModel: null,
                    linkId: null,
                    linkType: null,
                    linkClassName: null,
                  },
                  id: 240012,
                  nodeType: "list",
                  nodeId: "2q6g8hheh0o000",
                  parentId: "root",
                },
                {
                  prev: null,
                  values: {
                    null: null,
                  },
                  name: "InputException",
                  link: {
                    linkModel: null,
                    linkId: null,
                    linkType: null,
                    linkClassName: null,
                  },
                  id: 240013,
                  nodeType: "list",
                  nodeId: "5izm1hqnqy4000",
                  parentId: "root",
                },
                {
                  prev: null,
                  values: {
                    null: null,
                  },
                  name: "OutputRecords",
                  link: {
                    linkModel: null,
                    linkId: null,
                    linkType: null,
                    linkClassName: null,
                  },
                  id: 240014,
                  nodeType: "list",
                  nodeId: "5g8oln4uzmg00",
                  parentId: "root",
                },
                {
                  prev: null,
                  values: {
                    null: null,
                  },
                  name: "OutputSummary",
                  link: {
                    linkModel: null,
                    linkId: null,
                    linkType: null,
                    linkClassName: null,
                  },
                  id: 240015,
                  nodeType: "list",
                  nodeId: "5fatjqr2s9w000",
                  parentId: "root",
                },
                {
                  prev: null,
                  values: {
                    null: null,
                  },
                  name: "OutputSummaryRest",
                  link: {
                    linkModel: null,
                    linkId: null,
                    linkType: null,
                    linkClassName: null,
                  },
                  id: 240016,
                  nodeType: "list",
                  nodeId: "2seprv6boxu000",
                  parentId: "root",
                },
                {
                  prev: null,
                  values: {
                    null: null,
                  },
                  name: "OutputException",
                  link: {
                    linkModel: null,
                    linkId: null,
                    linkType: null,
                    linkClassName: null,
                  },
                  id: 240017,
                  nodeType: "list",
                  nodeId: "2ix66yzvsvm000",
                  parentId: "root",
                },
                {
                  prev: null,
                  values: {
                    null: null,
                  },
                  name: "BOM",
                  link: {
                    linkModel: null,
                    linkId: null,
                    linkType: null,
                    linkClassName: null,
                  },
                  id: 240018,
                  nodeType: "list",
                  nodeId: "19cb275jpkv400",
                  parentId: "root",
                },
                {
                  prev: null,
                  values: {
                    null: null,
                  },
                  name: "WorkNotice",
                  link: {
                    linkModel: "logic",
                    linkId: null,
                    linkType: "logic",
                    linkClassName: "WorkNotice",
                  },
                  id: 240019,
                  nodeType: "list",
                  nodeId: "b1ye1fv0ork00",
                  parentId: "root",
                },
                {
                  prev: null,
                  values: {
                    null: null,
                  },
                  name: "WorkUnit",
                  link: {
                    linkModel: "twins",
                    linkId: 6,
                    linkType: "workunit",
                    linkClassName: "ReductionWorkUnit",
                  },
                  id: 240020,
                  nodeType: "list",
                  nodeId: "347qm90vfsm000",
                  parentId: "root",
                },
                {
                  prev: null,
                  values: {
                    null: null,
                  },
                  name: "Statistics",
                  link: {
                    linkModel: null,
                    linkId: null,
                    linkType: null,
                    linkClassName: null,
                  },
                  id: 240021,
                  nodeType: "list",
                  nodeId: "13jc36kxmfk000",
                  parentId: "root",
                },
              ],
            },
          },
        ];
      },
    },
    tpl: {
      default: function () {
        return {};
      },
    },
    config: {
      default: function () {
        return {};
      },
    },
  },
};
</script>

<style lang="less">
.left-container {
  width: 100%;
  // height: calc(~"100vh - 140px");
  overflow: auto;
  min-height: 100px;
  .gantt_layout_root {
    height: calc(~"100vh - 200px") !important;
  }
}
.week_end {
  background: #f4f7f4 !important;
}
.nonworkday {
  background: #f0dfe5 !important;
}
.gantt_task_line,
.gantt_line_wrapper {
  margin-top: -9px;
}
.gantt_side_content {
  margin-bottom: 7px;
}
.gantt_task_link .gantt_link_arrow {
  margin-top: -12px !important;
}
.gantt_side_content.gantt_right {
  bottom: 0;
}
.baseline {
  position: absolute;
  border-radius: 2px;
  opacity: 0.6;
  margin-top: -7px;
  height: 12px;
  background: #ffd180;
  border: 1px solid rgb(255, 153, 0);
}
.summary-row,
.summary-row.odd {
  background-color: #eeeeee !important;
  font-weight: bold;
}
.gantt_grid div,
.gantt_data_area div {
  font-size: 12px;
}
.summary-bar {
  opacity: 0.4;
}
.gantt_task_cell.week_end {
  background-color: #eff5fd;
}
.gantt_task_row.gantt_selected .gantt_task_cell.week_end {
  background-color: #f8ec9c;
}
.slack {
  position: absolute;
  border-radius: 0;
  opacity: 0.7;

  border: none;
  border-right: 1px solid #b6b6b6;
  margin-left: -2px;
  background: #b6b6b6;
  background: repeating-linear-gradient(
    45deg,
    #ffffff,
    #ffffff 5px,
    #b6b6b6 5px,
    #b6b6b6 10px
  );
}
.btn {
  font: 500 14px Roboto;
  border: 1px solid #d9d9d9;
  border-radius: 2px;
  background: #fff;
  padding: 4px 12px;
  margin: 0 5px;
  color: rgba(0, 0, 0, 0.7);
  line-height: 20px;
  outline-color: #fffafa;
}
.complete_button {
  margin-top: 1px;
  background-image: url("../v_complete.png");
  width: 20px;
}
</style>